package hyl.core.fun;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import hyl.core.MyFun;
import hyl.core.reflect.MyKryo;
import hyl.core.run.IDo1;

/**
 * 与字节解析相关的函数<br>
 * 
 * 例如取字节部分内容<br>
 * 
 * 把字节转成map 或反转<br>
 * 
 * 
 * @author 37798955@qq.com
 *
 */
public class MyByte {
	public static void showbyte(byte[] bt3) {
		for (byte b : bt3) {
			System.out.print(b);
		    System.out.print(' ');
		}
		System.out.println();
	
	}
	/**
	 * 全部置1
	 * 
	 * @param 字节数
	 * @return
	 */
	public static byte[] ones(int 字节数) {
		byte[] bs = new byte[字节数];
		return ones(bs);
	}

	/**
	 * 全部置0
	 * 
	 * @param 字节数
	 * @return
	 */
	public static byte[] zeros(int 字节数) {
		byte[] bs = new byte[字节数];

		return zeros(bs);
	}

	/**
	 * 全部置1
	 * 
	 * @param 字节数
	 * @return
	 */
	public static byte[] ones(byte[] bs) {
		for (int i = 0; i < bs.length; i++) {
			bs[i] = (byte) 0xFF;
		}
		return bs;
	}

	/**
	 * 全部置0
	 * 
	 * @param 字节数
	 * @return
	 */
	public static byte[] zeros(byte[] bs) {
		for (int i = 0; i < bs.length; i++) {
			bs[i] = (byte) 0;
		}
		return bs;
	}

	/**
	 * 以最长的 byte[] 长度为基准
	 * 
	 * 或多个byte[]
	 * 
	 * @param 源
	 * @return
	 */
	public static byte[] orBytes(byte[]... 源) {
		if (源 == null)
			return null;
		byte[] c = 源[0];
		if (源.length > 1)
			for (int i = 1; i < 源.length; i++) {
				c = orBytes(c, 源[i]);
			}
		return c;
	}

	/**
	 * 以最长的 byte[] 长度为基准
	 * 
	 * 或多个byte[]
	 * 
	 * @param 源
	 * @return
	 */
	public static byte[] orBytes(List<byte[]> 源) {
		if (源 == null || 源.isEmpty())
			return null;
		byte[] c = 源.get(0);
		for (byte[] b : 源) {
			c = orBytes(c, b);
		}
		return c;
	}

	/**
	 * 以最长的 byte[] 长度为基准
	 * 
	 * 或2个byte[]
	 */
	public static byte[] orBytes(byte[] a, byte[] b) {
		if (a == null && b != null)
			return b;
		if (b == null && a != null)
			return a;
		byte[] c, d;
		if (a.length >= b.length) {
			c = MyFun.copy(a);
			d = b;
		} else {
			c = MyFun.copy(b);
			d = a;
		}
		for (int i = 0; i < d.length; i++) {
			c[i] = (byte) (c[i] | d[i]);
		}
		return c;
	}
	/**
	 * 以最长的 byte[] 长度为基准,找出全1 的位置
	 * 
	 * 与多个byte[]
	 * 
	 * @param 源
	 * @return
	 */
	public static byte[] andBytes(byte[]... 源) {
		if (源 == null)
			return null;
		byte[] c = 源[0];
		if (源.length > 1)
			for (int i = 1; i < 源.length; i++) {
				c = andBytes(c, 源[i]);
			}
		return c;
	}
	/**
	 * 以最长的 byte[] 长度为基准,找出全1 的位置
	 * 
	 * 与多个byte[]
	 * 
	 * @param 源
	 * @return
	 */
	public static byte[] andBytes(List<byte[]> 源) {
		if (源 == null || 源.isEmpty())
			return null;
		byte[] c = 源.get(0);
		for (byte[] b : 源) {
			c = andBytes(c, b);
		}
		return c;
	}
	/**
	 * 以最长的 byte[] 长度为基准,找出全1 的位置
	 * 
	 * 与2个byte[]
	 */
	public static byte[] andBytes(byte[] a, byte[] b) {
		if (a == null && b != null)
			return b;
		if (b == null && a != null)
			return a;
		byte[] c, d;
		if (a.length >= b.length) {
			c = MyFun.copy(a);
			d = b;
		} else {
			c = MyFun.copy(b);
			d = a;
		}
		for (int i = 0; i < d.length; i++) {
			c[i] = (byte) (c[i] & d[i]);
		}
		return c;
	}


	/**
	 * 以最长的 byte[] 长度为基准,一般只用于两个数的异或,多个数的异或没有意义
	 * 
	 * 异或2个byte[]
	 */
	public static byte[] xorBytes(byte[] a, byte[] b) {
		if (a == null)
			return b;
		if (b == null)
			return a;
		byte[] c, d;
		if (a.length >= b.length) {
			c = MyFun.copy(a);
			d = b;
		} else {
			c = MyFun.copy(b);
			d = a;
		}
		for (int i = 0; i < d.length; i++) {
			c[i] = (byte) (c[i] ^ d[i]);
		}
		return c;
	}

	/**
	 * 截取字节数组
	 * 
	 * @param 源
	 * @param 开始位置
	 * @param 读取长度
	 * @return
	 */
	public static byte[] subBytes(byte[] 源, int 开始位置, int 读取长度) {
		if (源 == null)
			return null;
		if (开始位置 > 源.length)
			return null;
		if (开始位置 < 0)
			开始位置 = 0;
		if (读取长度 + 开始位置 > 源.length)
			读取长度 = 源.length - 开始位置;
		if (读取长度 == 0)
			return null;
		return moveBytes(源, 开始位置, 读取长度);
	}

	/**
	 * 截取部分数据
	 * 
	 * @param 源
	 * @param 开始位置
	 * @return
	 */
	public static byte[] subBytes(byte[] 源, int 开始位置) {
		if (源 == null)
			return null;
		if (开始位置 > 源.length)
			return null;
		if (开始位置 < 0)
			开始位置 = 0;
		int len = 源.length - 开始位置;
		return moveBytes(源, 开始位置, len);
	}

	/**
	 * 从byte[] 数组中移出数据
	 * 
	 * @param 源
	 * @param 开始位置
	 * @param 长度
	 * @return
	 */
	private static byte[] moveBytes(byte[] 源, int 开始位置, int 长度) {
		byte[] bs = new byte[长度];
		for (int i = 0; i < 长度; i++) {
			bs[i] = 源[开始位置 + i];
		}
		return bs;
	}

	/**
	 * 判断a 是否包含b
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static boolean do包含(byte[] a, byte[] b) {
		if (a.length >= b.length) {
			for (int i = 0; i < b.length; i++) {
				if (a != b)
					return false;
			}
			return true;
		} else
			return false;
	}

	/**
	 * 打包byte[]集合成 单个byte[] 打包的结果分头和体两个部分 <br>
	 * 
	 * 头是byte[]长度联合 体是byte[] 联合 已测试
	 * 
	 * @param datas
	 * @return
	 */
	public static byte[] packBytes(List<byte[]> datas) {
		if (datas == null || datas.isEmpty())
			return null;
		int num = datas.size();
		int[] l4 = new int[num];
		int i = 0, datalen = 0;
		for (byte[] data : datas) {
			l4[i] = MyFun.get字节数(data);
			datalen += (4 + l4[i]);
			i++;
		}
		byte[] bs = new byte[4 * num + datalen];
		int index = 0;
		for (i = 0; i < num; i++) {
			byte[] blen = MyFun.int2ByteArray(l4[i]);
			System.arraycopy(blen, 0, bs, index, 4);
			index += 4;
			if (datas.get(i) != null) {
				System.arraycopy(datas.get(i), 0, bs, index, l4[i]);
				index += l4[i];
			}
		}
		return bs;
	}

	/**
	 * 打包byte[]集合成 单个byte[] 已测试
	 * 
	 * @param datas
	 * @return
	 */
	public static byte[] packBytes(byte[]... datas) {
		int num = datas.length;
		int[] l4 = new int[num];
		int datalen = 0;
		for (int i = 0; i < num; i++) {
			l4[i] = MyFun.get字节数(datas[i]);
			datalen += l4[i];
		}
		byte[] bs = new byte[4 * num + datalen];
		int index = 0;
		for (int i = 0; i < num; i++) {
			byte[] blen = MyFun.int2ByteArray(l4[i]);
			System.arraycopy(blen, 0, bs, index, 4);
			index += 4;
			if (datas[i] != null) {
				System.arraycopy(datas[i], 0, bs, index, l4[i]);
				index += l4[i];
			}
		}
		return bs;
	}

	/**
	 * 把byte[]拆解成list< byte[] >
	 * 
	 * @param data
	 * @return
	 */
	public static List<byte[]> parseBytes2(byte[] data) {
		int len = MyFun.get字节数(data);
		if (len == 0)
			return null;
		int start = 0;
		int klen = 0;
		byte[] key = null;
		List<byte[]> list = new ArrayList<>();
		while (start < len) {
			klen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (klen == 0)
				list.add(null);
			else {
				key = MyByte.subBytes(data, start, klen);
				start += klen;
				list.add(key);
			}
		}
		return list;
	}

	/**
	 * 把字节流拆解成多个byte[] 组成的集合<br>
	 * 已测试 拆分的原则:<br>
	 * 第一个字节是分组数<br>
	 * <br>
	 * 第二部分是 每组的长度的顺序集合<br>
	 * 第二个字节是第一组长度<br>
	 * 第三个字节是第二组长度<br>
	 * 以此类推<br>
	 * 
	 * <br>
	 * 第三部分是 每组的内容 长度在之前第二部分已经规定<br>
	 * 
	 * @param datas
	 * @return
	 */
	public static byte[][] parseBytes(byte[] datas) {
		int len = datas.length;
		List<byte[]> bb = new ArrayList<>();
		int start = 0;
		int ilen = 0;
		while (start < len) {
			ilen = MyFun.byteArray2Int(moveBytes(datas, start, 4));
			start += 4;
			if (ilen == 0) {
				bb.add(null);
			} else {
				bb.add(moveBytes(datas, start, ilen));
				start += ilen;
			}
		}
		return bb.toArray(new byte[0][]);
	}

	public static void parseBytes(byte[] datas, IDo1<byte[]> call) {
		int len = datas.length;

		int start = 0;
		int ilen = 0;
		while (start < len) {
			ilen = MyFun.byteArray2Int(moveBytes(datas, start, 4));
			start += 4;
			if (ilen > 0) {
				byte[] b = moveBytes(datas, start, ilen);
				call.run(b);
			}
		}

	}

	public static List<byte[]> bytess2List(byte[]... datas) {
		List<byte[]> bb = new ArrayList<>();
		for (int i = 0; i < datas.length; i++)
			bb.add(datas[i]);
		return bb;
	}

	public static byte[][] List2bytess(List<byte[]> datas) {
		return datas.toArray(new byte[0][]);
	}

	/** 不要使用 这种写法 非常慢 用kryo或fastjson 代替非常好 */
	public static <T> byte[] obj2bytes(T 对象) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(对象);
			return baos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/** 不要使用 这种写法 非常慢 用kryo或fastjson 代替非常好 */
	@SuppressWarnings("unchecked")
	public static <T> T bytes2obj(byte[] 数据) {
		ByteArrayInputStream bais = new ByteArrayInputStream(数据);
		ObjectInputStream ois;
		try {
			ois = new ObjectInputStream(bais);
			return(T) ois.readObject();
		
		} catch (IOException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	////////////////////////////////

	/**
	 * 拆包 把byte[] 拆解成 map<byte[],byte[]>
	 * 
	 * @param data
	 * @return
	 */
	public static Map<byte[], byte[]> bytes2MapB(byte[] data) {
		byte[] key = null, value = null;
		int klen = 0, vlen = 0;
		int start = 0;
		Map<byte[], byte[]> map = new HashMap<>();
		while (start < data.length) {
			klen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (klen == 0)
				continue;
			key = MyByte.subBytes(data, start, klen);
			start += klen;

			vlen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (vlen > 0) {
				value = MyByte.subBytes(data, start, vlen);
				start += vlen;
			}
			map.put(key, value);
		}
		return map;
	}

	/**
	 * 打包 map<byte[],byte[]> 成为 byte[]
	 * 
	 * @param map
	 * @return
	 */
	public static byte[] mapB2Bytes(Map<byte[], byte[]> map) {
		int len = 0;
		int klen = 0, vlen = 0;
		byte[] key = null, value = null;
		for (Map.Entry<byte[], byte[]> mp : map.entrySet()) {
			key = mp.getKey();
			if (key == null)
				continue;
			value = mp.getValue();
			klen = key.length;
			vlen = MyFun.get字节数(value);
			len += (8 + klen + vlen);
		}
		ByteBuffer bb = ByteBuffer.allocate(len);
		for (Map.Entry<byte[], byte[]> mp : map.entrySet()) {
			key = mp.getKey();
			if (key == null)
				continue;
			value = mp.getValue();
			klen = key.length;
			vlen = MyFun.get字节数(value);
			bb.put(MyFun.int2ByteArray(klen));
			bb.put(key);
			bb.put(MyFun.int2ByteArray(vlen));
			if (vlen > 0)
				bb.put(value);
		}
		return bb.array();
	}

	/**
	 * 拆包 把byte[] 拆解成 map<String,String>
	 * 
	 * @param data
	 * @return
	 */
	public static Map<String, String> bytes2MapS(byte[] data) {
		int start = 0;
		Map<String, String> map = new HashMap<>();
		String value = null;
		String key = null;
		int klen = 0, vlen = 0;
		while (start < data.length) {
			value = null;
			key = null;
			klen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (klen == 0)
				continue;
			key = MyFun.bytes2U8str(MyByte.subBytes(data, start, klen));
			start += klen;
			vlen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (vlen > 0) {
				value = MyFun.bytes2U8str(MyByte.subBytes(data, start, vlen));
				start += vlen;
			}
			map.put(key, value);
		}
		return map;
	}

	/**
	 * 打包 map<String,String> 成为 byte[]
	 * 
	 * @param map
	 * @return
	 */
	public static byte[] mapS2Bytes(Map<String, String> map) {
		if (map == null || map.isEmpty())
			return null;
		List<byte[]> list = new ArrayList<>();
		int klen = 0, vlen = 0;
		byte[] key = null, value = null;
		for (Map.Entry<String, String> mp : map.entrySet()) {
			key = MyFun.u8str2Bytes(mp.getKey());
			if (key == null)
				continue;
			value = MyFun.u8str2Bytes(mp.getValue());
			klen = MyFun.get字节数(key);
			vlen = MyFun.get字节数(value);
			list.add(MyFun.int2ByteArray(klen));
			list.add(key);
			list.add(MyFun.int2ByteArray(vlen));
			if (vlen > 0)
				list.add(value);

		}
		return MyFun.concat(list);
	}

	/**
	 * 拼接 集合成byte[]<br>
	 * 与MyFun.concat 区别在于 它包含空值<br>
	 * 而且会 把每个项的长度计算出来, 插在每个项的前面<br>
	 * 
	 * @param list
	 * @return
	 */
	public static byte[] listB2Bytes(byte[]... list) {
		if (list == null || list.length == 0)
			return null;
		int len = 0;
		int klen = 0;
		for (byte[] data : list) {
			klen = MyFun.get字节数(data);
			len += (4 + klen);
		}
		ByteBuffer bb = ByteBuffer.allocate(len);
		for (byte[] data : list) {
			klen = MyFun.get字节数(data);
			bb.put(MyFun.int2ByteArray(klen));
			if (klen == 0)
				continue;
			bb.put(data);
		}
		return bb.array();
	}

	/**
	 * 把byte[] 拆解成list<String>
	 * 
	 * 保留空值
	 * 
	 * @param data
	 * @return
	 */
	public static List<String> bytes2ListS(byte[] data) {
		int len = MyFun.get字节数(data);
		if (len == 0)
			return null;
		int start = 0;
		int klen = 0;
		String key = null;
		List<String> list = new ArrayList<>();
		while (start < len) {
			klen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (klen == 0)
				list.add(null);
			else {
				key = MyFun.bytes2U8str(MyByte.subBytes(data, start, klen));
				start += klen;
				list.add(key);
			}
		}
		return list;
	}

	/**
	 * 把 数据集合 list<String> 拼成字节
	 * 
	 * 不同于 MyFun.concat 只是单纯的拼接
	 * 
	 * 保留空值
	 * 
	 * @param list
	 * @return
	 */

	public static byte[] listS2Bytes(List<String> 数据) {
		if (数据 == null || 数据.isEmpty())
			return null;
		List<byte[]> list = new ArrayList<>();
		byte[] key = null;
		int klen = 0;
		for (String item : 数据) {
			key = MyFun.u8str2Bytes(item);
			klen = MyFun.get字节数(key);
			list.add(MyFun.int2ByteArray(klen));
			list.add(key);
		}
		return MyFun.concat(list);
	}

	public static <T> byte[] listT2Bytes(List<T> 数据) {
		if (数据 == null || 数据.isEmpty())
			return null;
		MyKryo kyro = MyKryo.getInstance();
		List<byte[]> list = new ArrayList<>();
		byte[] key = null;
		for (T item : 数据) {
			key = kyro.serialize(item);
			list.add(MyFun.int2ByteArray(key.length));
			list.add(key);
		}

		return MyFun.concat(list);
	}

	public static <T> List<T> bytes2ListT(byte[] data) {
		int len = MyFun.get字节数(data);
		MyKryo kyro = MyKryo.getInstance();
		if (len == 0)
			return null;
		int start = 0;
		int klen = 0;
		T key = null;
		List<T> list = new ArrayList<>();
		while (start < len) {
			klen = MyFun.byteArray2Int(MyByte.subBytes(data, start, 4));
			start += 4;
			if (klen == 0)
				list.add(null);
			else {
				key = kyro.deserialize(MyByte.subBytes(data, start, klen));
				start += klen;
				list.add(key);
			}
		}
		return list;
	}

	public static boolean like(byte[] o1, byte[] o2) {
		if (search(o1, 0, o2) > 0)
			return true;
		else
			return false;
	}

	public static boolean contain(byte[] arr, byte[] key) {
		if (arr == null || key == null)
			return false;
		if (key == null || arr.length < key.length)
			return false;
		for (int j = 0; j < key.length; j++) {
			if (arr[j] != key[j]) {
				return false;
			}
		}
		return true;
	}

	public static int search(byte[] arr, int beginPosition, byte[] key) {
		if (arr == null || arr.length < beginPosition)
			return -1;

		if (key == null || (arr.length - beginPosition) < key.length)
			return -1;
		int i = beginPosition;
		boolean flag = true;
		byte b = key[0];
		for (i = beginPosition; i < arr.length; i++) {
			if (arr[i] == b) {
				for (int j = 1; j < key.length; j++) {
					if (arr[i + j] != key[j]) {
						flag = false;
						break;
					}
				}
				if (flag) {
					return i;// 大于0
				} else {
					flag = true;
				}
			}
		}
		return -1;
	}

	private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
			'F' };

	/**
	 * 十六进制转化为二进制
	 */
	public static byte[] hexToBytes(String hexString) {
		if (hexString == null) {
			return null;
		}
		if (hexString.length() == 0) {
			return new byte[0];
		}
		byte[] byteArray = new byte[hexString.length() / 2];
		for (int i = 0; i < byteArray.length; i++) {
			String subStr = hexString.substring(2 * i, 2 * i + 2);
			byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
		}
		return byteArray;
	}

	/**
	 * 二进制转化为十六进制
	 */
	public static String bytesToHex(byte[] byteArray) {
		if (byteArray == null) {
			return null;
		}
		char[] hexChars = new char[byteArray.length * 2];
		for (int j = 0; j < byteArray.length; j++) {
			int v = byteArray[j] & 0xFF;
			hexChars[j * 2] = HEX_CHARS[v >>> 4];
			hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
		}
		return new String(hexChars);
	}

	public static String bytesToHex(byte bytes[], int m, int len) {
		StringBuffer stringbuffer = new StringBuffer(2 * len);
		int k = len + m;
		for (int l = m; l < k; l++) {
			byte bt = bytes[l];
			char c0 = HEX_CHARS[(bt & 0xf0) >> 4];
			char c1 = HEX_CHARS[bt & 0xf];
			stringbuffer.append(c0);
			stringbuffer.append(c1);
		}
		return stringbuffer.toString();
	}

	// 二进制转十六进制

//	public static String bytesToHex2(byte[] bytes) {
//		StringBuffer stringBuffer = new StringBuffer();
//		for (int i = 0; i < bytes.length; i++) {
//			String temp = Integer.toHexString(bytes[i] & 0xFF);
//			if (temp.length() == 1) {
//				// 16进制数值长度为2,长度为1时补0
//				stringBuffer.append("0");
//			}
//			stringBuffer.append(temp);
//		}
//		return stringBuffer.toString();
//	}
	/**
	 * 异或某位==反选
	 * 
	 * @param bytes
	 * @param n
	 */
	public static void xorBit(byte[] bytes, int n) {
		int j = n % 8;
		int i = n / 8;
		int b = 0x80;
		if (j > 0)
			b = b >> j;
		bytes[i] = (byte) (b ^ bytes[i]);
	}
/**
 * 设置某位
 * @param bytes
 * @param n
 */
	public static void setBit(byte[] bytes, int n) {
		int j = n % 8;
		int i = n / 8;
		int b = 0x80;
		if (j > 0)
			b = b >> j;
		bytes[i] = (byte) (b | bytes[i]);
	}
/**
 * 获取某位
 * @param bytes
 * @param n
 * @return
 */
	public static boolean getBit(byte[] bytes, int n) {
		int j = n % 8;
		int i = n / 8;
		int b = 0x80;
		if (j > 0)
			b = b >> j;
		int c = (byte) (b & bytes[i]);
		return c > 0;

	}

	/**
	 * 不带分隔符 二进制字符串转 字节数组
	 * 
	 * @param bytes
	 * @return
	 */
	public static byte[] binToBytes(String hexString) {
		// 把字符串转成字符数组
		int len = hexString.length();
		int n = len / 8 + (len % 8 == 0 ? 0 : 1);
		byte[] bb = new byte[n];
		int k = 0;
		for (int i = 0; i < n; i++) {
			int bit = 0x80;
			byte b = 0;
			for (int j = 0; j < 8 && k < len; j++) {
				char c = hexString.charAt(k);
				if (c == '1')
					b = (byte) (bit | b);
				bit = bit >> 1;
				k++;
			}
			bb[i] = b;
		}
		return bb;
	}

	/**
	 * 
	 * 字节转 二进制字符串 不带分隔符
	 * 
	 * @param bytes
	 * @return
	 */
	public static String bytesToBin(byte[] bytes) {
		// 把字符串转成字符数组
		int len = bytes.length;
		StringBuffer stringbuffer = new StringBuffer(8 * len);
		for (int i = 0; i < len; i++) {
			int bit = 0x80;
			byte b = bytes[i];
			for (int j = 0; j < 8; j++) {
				if ((b & bit) == bit)
					stringbuffer.append("1");
				else
					stringbuffer.append("0");
				b = (byte) (b << 1);
			}
		}
		return stringbuffer.toString();
	}

	/**
	 * 带分隔符二进制字符串转 字节数组
	 * 
	 * @param binString
	 * @param 分隔符
	 * @return
	 */
	public static byte[] binToBytes(String binString, char 分隔符) {
		// 把字符串转成字符数组
		int len = binString.length();
		int n = (len / 9) + ((len % 9) == 0 ? 0 : 1);
		byte[] bb = new byte[n];
		int k = 0;
		for (int i = 0; i < n; i++) {
			int bit = 0x80;
			byte b = 0;
			for (int j = 0; j < 9 && k < len; j++) {
				char c = binString.charAt(k++);
				if (c == 分隔符)
					continue;
				if (c == '1')
					b = (byte) (bit | b);
				bit = bit >> 1;

			}
			bb[i] = b;
		}
		return bb;
	}

	/**
	 * 字节转 二进制字符串 带分隔符
	 * 
	 * @param bytes
	 * @param c
	 * @return
	 */
	public static String bytesToBin(byte[] bytes, char c) {
		// 把字符串转成字符数组
		int len = bytes.length;
		StringBuffer stringbuffer = new StringBuffer(8 * len);
		for (int i = 0; i < len; i++) {
			int bit = 0x80;
			byte b = bytes[i];
			stringbuffer.append(c);
			for (int j = 0; j < 8; j++) {
				if ((b & bit) == bit)
					stringbuffer.append("1");
				else
					stringbuffer.append("0");
				b = (byte) (b << 1);
			}
		}
		return stringbuffer.substring(1, stringbuffer.length());
	}

	public static ByteArrayInputStream toStream(byte[] arr) {
		ByteArrayInputStream bInput = new ByteArrayInputStream(arr);
		// 设置当前流的位置为流的开始
		return bInput;
	}

}